import tracker from "../utils/tracker";
import {onload} from '../utils/onload';
import getLastEvent from "../utils/getLastEvent";
import getSelector from "../utils/getSelector";

export function timing(){
  console.log('timing.js 正在进行性能监控  --- ---');


  //这些性能指标的时间都是相对时间
  //相对于fetchStart时的相对时间
  let FMP, LCP;

  //PerformanceObserver
  //IE 完全不支持
  //一些比较新的 entryTypes, 只有谷歌支持
  //https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver/supportedEntryTypes
  //https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry/entryType

  if(PerformanceObserver){
    //FMP
    new PerformanceObserver((entryList, observer) => {
      const perfEntries = entryList.getEntries();
      FMP = perfEntries[0];
      observer.disconnect(); // 只用观察一次
    }).observe({
      entryTypes: ['element'] // 观察页面中有意义的元素
    }); //← 需要搭配 h1.setAttribute('elementtiming', 'meaningful'), 才能拿到FMP

    //LCP
    new PerformanceObserver((entryList, observer) => {
      const perfEntries = entryList.getEntries();
      LCP = perfEntries[0];
      observer.disconnect();
    }).observe({
      entryTypes: ['largest-contentful-paint']
    });

    //FID First Input Delay(首次输入延迟)
    new PerformanceObserver((entryList, observer) => {
      const lastEvent = getLastEvent();
      const firstInput = entryList.getEntries()[0];
      console.log('FID:',firstInput);

      if(firstInput){
        //processingStart 开始处理的时间
        //startTime 开始点击的时间
        //差值就是处理的延迟
        const inputDelay = firstInput.processingStart - firstInput.startTime

        const duration = firstInput.duration; //处理的耗时

        if (inputDelay > 0 || duration > 0) {
          tracker.send({
            kind: 'experience', //用户体验指标
            type: 'firstInputDelay', //首次输入延迟
            startTime: firstInput.startTime, //用户点击时的时间
            inputDelay, //延迟的时间
            duration, //处理时间
            selector: lastEvent ? getSelector(lastEvent.path || lastEvent.target) : ''
          });
        }
      }

    }).observe({
      type: 'first-input', //用户的第一次也只会在第一次交互(点击鼠标时) 会触发回调
      buffered: true
    });
  }

  onload(() => {
    setTimeout(() => {
      const {
        // navigationStart:
        // When the prompt for unload terminates on the previous document in the same browsing context.
        // If there is no previous document, this value will be the same as PerformanceTiming.fetchStart.
        navigationStart,

        fetchStart,
        connectStart,
        connectEnd,
        requestStart,
        responseStart,
        responseEnd,
        domLoading,
        domInteractive,
        domContentLoadedEventStart,
        domContentLoadedEventEnd,
        loadEventStart,
        loadEventEnd
      } = performance.timing;

      tracker.send({
        kind: 'experience', //用户体验指标
        type: 'timing', //统计每个阶段的时间
        connectTime: connectEnd - connectStart, //连接时间

        // TTFB(Time To First Byte) 获得响应消息第一个字节的时间
        // 包含 DNS解析+TCP三次握手+HTTP请求+第一字节返回的
        ttfbTime: responseStart - /*navigationStart*/fetchStart,

        responseTime: responseEnd - responseStart,
        parseDOMTime: domInteractive - domLoading, //dom解析时间
        domContentLoadedTime: domContentLoadedEventEnd - domContentLoadedEventStart,
        timeToInteractive: domInteractive - /*navigationStart*/fetchStart,
        loadTime: loadEventStart - /*navigationStart*/fetchStart
      });

      if(performance){
        const FP = performance.getEntriesByName('first-paint')[0]
        const FCP = performance.getEntriesByName('first-contentful-paint')[0]
        console.log('FP', FP);
        console.log('FCP', FCP);
        console.log('FMP', FMP);
        console.log('LCP', LCP);
        tracker.send({
          kind: 'experience', //用户体验指标
          type: 'paint', //
          firstPaint: FP.startTime,
          firstContentfulPaint: FCP.startTime,
          firstMeaningfulPaint: FMP.startTime,
          largestContentfulPaint: LCP.startTime
        });
      }

    },3000);
  });
}
